package com.example.calendar.ui.screens.month

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.calendar.data.model.CalendarEvent
import com.example.calendar.data.repository.EventRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalTime
import org.threeten.bp.YearMonth
import javax.inject.Inject

/**
 * ViewModel for the month screen
 */
@HiltViewModel
class MonthViewModel @Inject constructor(
    private val eventRepository: EventRepository
) : ViewModel() {

    // Current year month shown in the calendar
    private val _yearMonth = MutableStateFlow(YearMonth.now())
    val yearMonth: StateFlow<YearMonth> = _yearMonth.asStateFlow()

    // Currently selected date
    private val _selectedDate = MutableStateFlow(LocalDate.now())
    val selectedDate: StateFlow<LocalDate> = _selectedDate.asStateFlow()

    // Events for the current month
    val monthEvents = combine(
        yearMonth,
        eventRepository.getAllEvents()
    ) { yearMonth, allEvents ->
        val firstDay = yearMonth.atDay(1).atStartOfDay()
        val lastDay = yearMonth.atEndOfMonth().atTime(LocalTime.MAX)
        allEvents.filter { event ->
            event.overlapsWith(firstDay, lastDay)
        }
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = emptyList()
    )

    // Events for the selected date
    val selectedDateEvents = combine(
        selectedDate,
        eventRepository.getAllEvents()
    ) { date, allEvents ->
        val startOfDay = date.atStartOfDay()
        val endOfDay = date.atTime(LocalTime.MAX)
        allEvents.filter { event ->
            event.overlapsWith(startOfDay, endOfDay)
        }
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = emptyList()
    )

    // Dates that have events this month
    val eventDates = combine(
        yearMonth,
        eventRepository.getAllEvents()
    ) { yearMonth, allEvents ->
        val firstDay = yearMonth.atDay(1).atStartOfDay()
        val lastDay = yearMonth.atEndOfMonth().atTime(LocalTime.MAX)
        
        allEvents
            .filter { event -> event.overlapsWith(firstDay, lastDay) }
            .flatMap { event ->
                val eventStart = event.startDateTime.toLocalDate()
                val eventEnd = event.endDateTime.toLocalDate()
                
                if (eventStart == eventEnd) {
                    listOf(eventStart)
                } else {
                    var currentDate = eventStart
                    val dates = mutableListOf<LocalDate>()
                    
                    while (!currentDate.isAfter(eventEnd)) {
                        dates.add(currentDate)
                        currentDate = currentDate.plusDays(1)
                    }
                    
                    dates
                }
            }
            .distinct()
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5000),
        initialValue = emptyList()
    )

    /**
     * Navigate to the previous month
     */
    fun navigateToPreviousMonth() {
        _yearMonth.value = _yearMonth.value.minusMonths(1)
    }

    /**
     * Navigate to the next month
     */
    fun navigateToNextMonth() {
        _yearMonth.value = _yearMonth.value.plusMonths(1)
    }

    /**
     * Navigate to the current month (today)
     */
    fun navigateToToday() {
        _yearMonth.value = YearMonth.now()
        _selectedDate.value = LocalDate.now()
    }

    /**
     * Select a date
     */
    fun selectDate(date: LocalDate) {
        _selectedDate.value = date
        
        // If the selected date is in a different month, change the month
        if (date.month != _yearMonth.value.month || date.year != _yearMonth.value.year) {
            _yearMonth.value = YearMonth.of(date.year, date.month)
        }
    }

    /**
     * Navigate to a specific year and month
     */
    fun navigateToYearMonth(year: Int, month: Int) {
        _yearMonth.value = YearMonth.of(year, month)
    }
} 